package ch.ifage.web;

import java.io.Serializable;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
//import org.apache.log4j.Logger;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.ChartSeries;
//import javax.enterprise.context.Conversation;
//import javax.enterprise.context.ConversationScoped;
import ch.ifage.business.dom.Assureur;
import ch.ifage.business.dom.Client;
import ch.ifage.business.dom.Police;
import ch.ifage.business.dom.Sinistre;
import ch.ifage.business.service.JPAImpl;
import ch.ifage.business.service.ServiceCourtier;

import org.primefaces.event.SelectEvent;

/**
 * Gestion des enregistrements c'est a dire des ajouts, modifications et suppressions des instances dans le service.
 * @author Betty Ba
 *
 */
/** Nom du Bean. */
@Named("manage")
@SessionScoped
public class GestionEnregistrements implements Serializable {

	/** logger par d�faut. */
	/** serial-Id. */
	private static final long serialVersionUID = 1L;
	/** Le client a enregister. */
	private Client mClient;
	/** L'assureur a enregister. */
	private Assureur mAssureur;
	/** La police a enregister. */
	private Police mPolice;
	/** Le sinistre a enregister. */
	private Sinistre mSinistre;
	/** Graphique montrant la prime et les indemnit�s. */
	private CartesianChartModel mCategoryModel;
	/** Etat d'un bouton d'enregistrement. */
	private boolean mBouton1Desactive;
	/** Etat d'un bouton d'enregistrement. */
	private boolean mBouton2Desactive;
	/** Evenement genere par un clique. */
	private SelectEvent mEvent1;
	/** Evenement genere par un clique. */
	private SelectEvent mEvent2;
	
	
	/** Service injecte au bean. */
	@Inject
	@JPAImpl
	private ServiceCourtier serviceClient;

	/**
	 * *Constructeur qui genere de nouvelles instances pour des enregistrements. les boutons d'enregistrement sont
	 * desactives par defaut
	 */
	public GestionEnregistrements() {
		this.mClient = new Client();
		this.mAssureur = new Assureur();
		this.mPolice = new Police();
		this.mSinistre = new Sinistre();
		this.setBouton1Desactive(true);
		this.setBouton2Desactive(true);
	}
	
	/**
	 * * @param event Lorsqu'une police est selectionnee, le bouton d'enregistrement est active pour enregistrer un
	 * nouveau sinistre.
	 */
	public void onRowSelectP(final SelectEvent event) {
		FacesMessage msg = new FacesMessage("Policy Selected", ((Police) event.getObject()).getNumeroPolice());
		FacesContext.getCurrentInstance().addMessage(null, msg);
		this.activerBouton1();
	}

	/**
	 * * @param event1 Losqu'un client est s�lectionn�, le bouton d'enregistrement est active pour enregister une
	 * nouvelle police.
	 */
	public void onRowSelectC(final SelectEvent event1) {
		this.mEvent1 = event1;
		FacesMessage msg = new FacesMessage("Customer Selected", ((Client) event1.getObject()).getRaisonSociale());
		FacesContext.getCurrentInstance().addMessage(null, msg);
		this.activerBouton2();

	}

	/**
	 * * @param event2 Losqu'un assureur est s�lectionn�, le bouton d'enregistrement est activ� pour enregistrer une
	 * nouvelle police.
	 */
	public void onRowSelectA(final SelectEvent event2) {
		this.mEvent2 = event2;
		FacesMessage msg = new FacesMessage("Insurer Selected", ((Assureur) event2.getObject()).getRaisonSociale());
		FacesContext.getCurrentInstance().addMessage(null, msg);
		this.activerBouton2();
	}

	/** * @return l'etat du bouton1. */
	public boolean getBouton1Desactive() {
		return mBouton1Desactive;
	}

	/**
	 * * @param bouton1Desactive active ou d�sactive le bouton1.
	 */
	public void setBouton1Desactive(final boolean bouton1Desactive) {
		this.mBouton1Desactive = bouton1Desactive;
	}

	/** * @return l'etat du bouton2. */
	public boolean getBouton2Desactive() {
		return mBouton2Desactive;
	}

	/**
	 * * @param bouton2Desactive active ou d�sactive le bouton2.
	 */
	public void setBouton2Desactive(final boolean bouton2Desactive) {
		this.mBouton2Desactive = bouton2Desactive;
	}

	/**
	 * * @param active bouton1.
	 */
	public void activerBouton1() {
		this.setBouton1Desactive(false);
	}

	/**
	 * * @param Si une police et un client sont s�lectionn�s, le bouton d'enregistrement est activ� pour enregsitrer un
	 * nouveau sinistre.
	 */
	public void activerBouton2() {
		if (mEvent1 == null || mEvent2 == null) {
			this.setBouton2Desactive(true);
		} else {
			this.setBouton2Desactive(false);
		}
	}
	/** * @return ajoute un client au service et renvoie vers la liste des clients. */
	public String ajouterClient() {
		this.serviceClient.ajouter(this.mClient);
		// this.mConversation.end();
		return "verslisteclients";
	}

	/**
	 * * @return ajoute une police au service, lui attribue un assureur et un client et renvoie vers la liste des
	 * polices.
	 */
	public String ajouterPolice() {
		this.mClient.getListePolices().add(this.mPolice);
		this.mAssureur.getListePolices().add(this.mPolice);
		this.mPolice.setAssureur(this.mAssureur);
		this.mPolice.setClient(this.mClient);
		this.serviceClient.ajouter(this.mPolice);
		// this.mConversation.end();
		return "verslistepolices";
	}

	/**
	 * * @return ajoute un sinistre, lui attribue une police et renvoie vers la liste des sinistres.
	 */
	public String ajouterSinistre() {
		this.mPolice.getListeSinistres().add(this.mSinistre);
		this.mSinistre.setPolice(this.mPolice);
		this.serviceClient.ajouter(this.mSinistre);
		// this.mConversation.end();
		return "verslistesinistres";
	}

	/** * @return ajoute un assureur au service et renvoie vers la liste des assureurs. */
	public String ajouterAssureur() {
		this.serviceClient.ajouter(this.mAssureur);
		// this.mConversation.end();
		return "verslisteassureurs";

	}
	/** * @return modification du client. */
	public String modifierClient() { 
		this.serviceClient.modifier(this.mClient);
		return "refresh";
		
	}
	/** * @return modification de l'assureur. */
	public String modifierAssureur() {
		this.serviceClient.modifier(this.mAssureur);
		return "refresh";
		
	}
	/** * @return modification de la police. */
	public String modifierPolice() {
		this.serviceClient.modifier(mPolice);
		return "refresh";
	}
	
	/** * @return modification du sinistre. */
	public String modifierSinistre() {
		this.serviceClient.modifier(mSinistre);
		return "refresh";
	}

	/**
	 * * @param en cliquant sur le bouton de modification dans le formulaire les informations actuelles du client sont affichees.
	 */
	public void boutonModifierClient() {	
		this.serviceClient.setClientNouvelleRaisonSociale(this.mClient.getRaisonSociale());
		this.serviceClient.setClientNouveauDomaineActivite(this.mClient.getDomaineActivite());
		this.serviceClient.setClientNouveauResponsable(this.mClient.getResponsable());
		this.serviceClient.setClientNouvelleAdresse(this.mClient.getAdresse());
		this.serviceClient.setClientNouveauTelephone(this.mClient.getTelephone());
		this.serviceClient.setClientNouvelEmail(this.mClient.getEmail());
	}
	
	/**
	 * * @param en cliquant sur le bouton de modification dans le formulaire les informations actuelles de l'assureur sont affichees.
	 */
	public void boutonModifierAssureur(){
		
		this.serviceClient.setAssureurNouvelleRaisonSociale(this.mAssureur.getRaisonSociale());
		this.serviceClient.setAssureurNouveauResponsable(this.mAssureur.getResponsable());
		this.serviceClient.setAssureurNouvelleAdresse(this.mAssureur.getAdresse());
		this.serviceClient.setAssureurNouveauTelephone(this.mAssureur.getTelephone());
		this.serviceClient.setAssureurNouvelEmail(this.mAssureur.getEmail());
	}
	
	/**
	 * * @param en cliquant sur le bouton de modification dans le formulaire les informations actuelles de la police sont affichees.
	 */
	public void boutonModifierPolice() {
		this.serviceClient.setPoliceNouveauNumero(this.mPolice.getNumeroPolice());
		this.serviceClient.setPoliceNouvelleDateDebut(this.mPolice.getDateDebut());
		this.serviceClient.setPoliceNouvelleDateFin(this.mPolice.getDateFin());
		this.serviceClient.setNouvellePrime(this.mPolice.getPrime());
		
	}
	/**
	 * * @param en cliquant sur le bouton de modification dans le formulaire les informations actuelles du sinistre sont affichees.
	 */
	public void boutonModifierSinistre() {
		this.serviceClient.setSinistreNouveauNumero(this.mSinistre.getNumeroSinistre());
		this.serviceClient.setNouveauPrenom(this.mSinistre.getPrenom());
		this.serviceClient.setNouveauNom(this.mSinistre.getNom());
		this.serviceClient.setSinistreNouvelleDateDebut(this.mSinistre.getDateDebut());
		this.serviceClient.setSinistreNouvelleDateFin(this.mSinistre.getDateFin());
		this.serviceClient.setNouvelleIndemnite(this.mSinistre.getIndemnite());	
	}

	/**
	 * * @param p une police.
	 * 
	 * @return le total des indemnites versees pour une police donnee.
	 */
	public double total(Police p) {
		
		double total = 0.00;

		for (int i = 0; i < this.serviceClient.getSinistresPolice(p).size(); i++) {
			total += this.serviceClient.getSinistresPolice(p).get(i).getIndemnite();
		
		/*for (int i = 0; i < p.getListeSinistres().size(); i++) {
			total += p.getListeSinistres().get(i).getIndemnite();
		 */
		}
		return total;
		
	}

	/**
	 * * @param c desactive toutes les polices d'un client supprime en leur attribuant le statut X.
	 */
	public void desactiverPolices(final Client c) {
		for (int i = 0; i < c.getListePolices().size(); i++) {
			c.getListePolices().get(i).setActif(false);
			c.getListePolices().get(i).setStatut("X");
		}

	}

	/**
	 * * @param a desactive toutes les polices d'un assureur supprime en leur attribuant le statut X.
	 */
	public void desactiverPolices(final Assureur a) {
		for (int i = 0; i < a.getListePolices().size(); i++) {
			a.getListePolices().get(i).setActif(false);
			a.getListePolices().get(i).setStatut("X");
		}

	}

	/**
	 * * @param p desactive tous les sinistres d'une police supprim�e en leur attribuant le statut X.
	 */
	public void desactiverSinistre(final Police p) {
		for (int i = 0; i < p.getListeSinistres().size(); i++) {
			p.getListeSinistres().get(i).setActif(false);
			p.getListeSinistres().get(i).setStatut("X");
		}

	}

	/**
	 * * @return supprime un client et desactive ses polices et sinistres puis raffraichi la page.
	 */
	public String supprimerClient() {
		this.serviceClient.supprimer(mClient);
		/*this.serviceClient.supprimer(this.getClientChoisi());
		this.desactiverPolices(this.getClientChoisi());
		for (int i = 0; i < this.getClientChoisi().getListePolices().size(); i++) {
			this.desactiverSinistre(this.getClientChoisi().getListePolices().get(i));
		}*/
		return "refresh";
	}

	/**
	 * * @return supprime un assureur et d�sactive ses polices et sinistres puis raffraichi la page.
	 */
	public String supprimerAssureur() {
		this.serviceClient.supprimer(this.mAssureur);
		/*this.desactiverPolices(this.getAssureurChoisi());
		for (int i = 0; i < this.getAssureurChoisi().getListePolices().size(); i++) {
			this.desactiverSinistre(this.getAssureurChoisi().getListePolices().get(i));
		}*/
		return "refresh";
	}

	/**
	 * * @return supprime une police et d�sactive ses sinistres puis raffraichi la page.
	 */
	public String supprimerPolice() {
		this.serviceClient.supprimer(mPolice);
		/*this.mPolice.getClient().getListePolices().remove(this.mPolice);
		this.mPolice.getAssureur().getListePolices().remove(this.mPolice);
		this.desactiverSinistre(this.getPoliceChoisie());*/
		return "refresh";
	}

	/**
	 * * @return supprime un sinistre puis raffraichi la page.
	 */
	public String supprimerSinistre() {
		this.serviceClient.supprimer(mSinistre);
		/*this.msinistre.getPolice().getListeSinistres().remove(msinistre);*/
		return "refresh";
	}
	/**
	 * * @param client specifie le client selectionne.
	 */
	public void setClientChoisi(final Client client) {
		this.mClient = client;
	}

	/**
	 * * @param police specifie le police selectionnee.
	 */
	public void setPoliceChoisie(final Police police) {
		this.mPolice = police;

	}

	/**
	 * * @param assureur sp�cifie l'assureur selectionne.
	 */
	public void setAssureurChoisi(final Assureur assureur) {
		this.mAssureur = assureur;

	}

	/**
	 * * @param sinistre specifie le sinistre selectionne.
	 */
	public void setSinistreChoisi(final Sinistre sinistre) {
		this.mSinistre = sinistre;
	}

	/** * @return le client selectione. */
	public Client getClientChoisi() {
		return this.getClient();
	}

	/** * @return la police selectionnee. */
	public Police getPoliceChoisie() {
		return this.getPolice();
	}

	/** * @return l'assureur selectionne. */
	public Assureur getAssureurChoisi() {
		return this.getAssureur();
	}

	/** * @return le sinistre selectionne. */
	public Sinistre getSinistreChoisi() {
		return this.getSinistre();
	}

	/** * @return le sinistre selectione. */
	public Client getClient() {
		return this.mClient;
	}

	/** * @return la police. */
	public Police getPolice() {
		return this.mPolice;
	}

	/** * @return l'assureur. */
	public Assureur getAssureur() {
		return this.mAssureur;
	}

	/** * @return le sinistre. */
	public Sinistre getSinistre() {
		return this.mSinistre;
	}
	/**
	 * * @param nServiceClient Le service a specifier.
	 */
	public void setServiceClient(final ServiceCourtier nServiceClient) {
		this.serviceClient = nServiceClient;
	}

	/** * @return le service. */
	public ServiceCourtier getServiceClient() {
		return this.serviceClient;
	}

	/**
	 * * @return creation d'un nouveau client puis redirection vers le formulaire d'enregsitrement.
	 */
	public String versnouveauclient() {
		this.mClient = new Client();
		// this.mConversation.begin();
		return "versnouveauclient";
	}

	/**
	 * * @return creation d'un nouvel assureur puis redirection vers le formulaire d'enregsitrement.
	 */
	public String versnouvelassureur() {
		this.mAssureur = new Assureur();
		// this.mConversation.begin();
		return "versnouvelassureur";
	}
	
	/**
	 * * @return creation d'une nouvelle police puis redirection le formulaire d'enregsitrement.
	 */
	public String versnouvellepolice() {
		this.mPolice = new Police();
		// this.mConversation.begin();
		return "versnouvellepolice";

	}

	/**
	 * * @return creation d'un nouveau sinistre puis redirection vers le formulaire d'enregsitrement.
	 */
	public String versnouveausinistre() {
		this.mSinistre = new Sinistre();
		// this.mConversation.begin();
		return "versnouveausinistre";

	}

	/**
	 * * @param p graphique montrant le rapport entre la prime et les indemnit�s pour une police donn�e.
	 * 
	 * @return graphique
	 */
	public CartesianChartModel categoryModel(final Police p) {
			
		this.mCategoryModel = new CartesianChartModel();

		ChartSeries indem = new ChartSeries();
		indem.setLabel("Indemnités");
		indem.set(p.getNumeroPolice(), this.total(p));

		ChartSeries pr = new ChartSeries();
		pr.setLabel("Prime");
		pr.set(p.getNumeroPolice(), p.getPrime());

		this.mCategoryModel.addSeries(indem);
		this.mCategoryModel.addSeries(pr);

		return this.mCategoryModel;

	}

	/**
	 * * @param prime hauteur du graphique, soit 150 unit�s de plus que le montant de la prime ainsi, visuellement, la
	 * prime ne plafonnera pas.
	 * 
	 * @return graphique
	 */
	public double hauteurGraphique(final Double prime) {

		double hauteurGraphique = prime + 150;

		return hauteurGraphique;
	}

	/** * @return deconnecte l'utilisateur de sa session et renvoie a la page d'accueil. */
	public String logout() {
		FacesContext ctx = FacesContext.getCurrentInstance();
		ExternalContext ectx = ctx.getExternalContext();
		ectx.invalidateSession();
		return "versaccueil";
	}
	
	/** * @return la liste des polices du client sélectionné. */
	public List<Police> getPolicesDuClient() {
		this.serviceClient.setPolicesDuClient(mClient);
		return this.serviceClient.getPolicesDuClient();
	}
	
	/** * @return la liste des polices de l'assureur sélectionné. */
	public List<Police> getPolicesAssureur() {
		this.serviceClient.setPolicesAssureur(mAssureur);
		return this.serviceClient.getPolicesAssureur();
	}
	
	/** * @return la liste depuis le service des clients trouves selon un critere de recherche. */
	public String clientsTrouves() {
		this.serviceClient.getClientsTrouves();
		return "refresh";
	}
	
	/** * @return la liste depuis le service des assureurs trouves selon un critere de recherche. */
	public String assureursTrouves() {
		this.serviceClient.getAssureursTrouves();
		return "refresh";
	}
	
	/** * @return la liste depuis le service des polices trouvees selon un critere de recherche. */
	public String policesTrouvees() {
		this.serviceClient.getPolicesTrouvees();
		return "refresh";
	}
	/** * @return la liste depuis le service des polices d'un client selon son id. */
	public String policesDuClientId() {
		this.serviceClient.getPolicesDuClientId();
		return "refresh";
	}
	
	/** * @return la liste depuis le service des polices d'un assureur selon son id. */
	public String policesAssureurId() {
		this.serviceClient.getPolicesAssureurId();
		return "refresh";
	}
	
	/** * @return la liste depuis le service des sinistres trouves selon un critere de recherche. */
	public String sinistresTrouves() {
		this.serviceClient.getSinistresTrouves();
		return "refresh";
	}
	
	/** * @return la liste des sinistre de la police selectionnee. */
	public List <Sinistre> getSinistresPolice() {
		this.serviceClient.setSinistresPolice(mPolice);
		return this.serviceClient.getSinistresPolice();
	}
	
	/** * @return rend le champs de recherche de client null afin de le reinitialiser. */
	public String annuleRechercheClient() {
		this.serviceClient.annuleRechercheClient();
		return "refresh";
	}
	
	/** * @return rend le champs de recherche d'un assureur null afin de le reinitialiser. */
	public String annuleRechercheAssureur() {
		this.serviceClient.annuleRechercheAssureur();
		return "refresh";
	}
	
	/** * @return rend le champs de recherche d'une police null afin de le reinitialiser. */
	public String annuleRecherchePolice() {
		this.serviceClient.annuleRecherchePolice();
		return "refresh";
	}
	
	/** * @return rend le champs de recherche d'un sinistre null afin de le reinitialiser. */
	public String annuleRechercheSinistre() {
		this.serviceClient.annuleRechercheSinistre();
		return "refresh";
	}
	
	/** * @return rend le champs de recherche d'une police selon id Client null, afin de le reinitialiser. */
	public String annuleRecherchePolicesDuClientId() {
		this.serviceClient.annuleRecherchePolicesClientId();
		return "refresh";
	}
	
	/** * @return rend le champs de recherche d'une police selon id Assureur null, afin de le reinitialiser. */
	public String annuleRecherchePolicesAssureurId() {
		this.serviceClient.annuleRecherchePolicesAssureurId();
		return "refresh";
	}


}
